Author(s): Zongcheng Li
reviewer(s): Ying Ge, Hui Huang Date:
2025-11-20
If you use this code in your work or research, we kindly request that you cite our publication:
Xiaofan Lu, et al. (2025). FigureYa: A Standardized Visualization Framework for Enhancing Biomedical Data Interpretation and Research Efficiency. iMetaMed. https://doi.org/10.1002/imm3.70005
这幅连线图很有趣,比FigureYa174squareCross多了两层信息:点的大小和颜色。
This line diagram is interesting because it has two more layers of information than FigureYa174squareCross: the size and color of the dots.
From https://www.biorxiv.org/content/10.1101/2020.07.21.214387v1
Figure 2: CellChat analysis of the communications between skin cells during wound repair. (a) Hierarchical plot shows the inferred intercellular communication network for TGFb signaling. Left and right panels highlight the autocrine and paracrine signaling to fibroblast states and other non-fibroblast skin cell states, respectively. Solid and open circles represent source and target, respectively. Circle sizes are proportional to the number of cells in each cell group. Edge colors are consistent with the signaling source.
类似的图: similar plot:
From https://molecular-cancer.biomedcentral.com/articles/10.1186/s12943-019-1066-3
Fig. 2 m6A regulators are correlated with the activation and inhibition of cancer pathways. a Network diagram demonstrating the correlation between m6A regulators and cancer pathways. Red represents a positive correlation, and blue represents a negative correlation. The size of the nodes corresponds to the number of links.
任意两组、多组连线,同时用颜色大小展示节点的更多信息,用连线的颜色粗细展示关系的类别强弱等信息。
根据自己数据的生物学意义,来排列各个节点的顺序。或许能够出现特殊的模式,从而展示出有意义的生物学规律。
上下左右连线的方法可参考FigureYa174squareCross。
Connect any two or multiple groups with lines, while using color and size to display additional node information, and the color/thickness of the connecting lines to represent relationship categories and strengths.
Arrange the order of nodes based on the biological significance of your data. This may reveal unique patterns, thereby demonstrating meaningful biological insights.
For methods of connecting nodes (top, bottom, left, right), refer to FigureYa174squareCross
## 开始安装R包...
## Starting R package installation...
## ===========================================
## 包已安装: ggplot2
## Package already installed: ggplot2
## 包已安装: scales
## Package already installed: scales
## 包已安装: dplyr
## Package already installed: dplyr
##
## ===========================================
## 验证安装结果:
## Verifying installation results:
## ✓ ggplot2 已成功安装
## ✓ ggplot2 installed successfully
## ✓ scales 已成功安装
## ✓ scales installed successfully
## ✓ dplyr 已成功安装
## ✓ dplyr installed successfully
##
## 所有包已成功安装!
##
## All packages installed successfully!
## 您现在可以使用以下代码加载这些包:
## You can now load these packages with the following code:
## library(ggplot2)
## library(scales) # 提供数据缩放和颜色调整功能 / Provides data scaling and color adjustment functions
## library(dplyr) # 提供数据操作和管道操作符 %>% / Provides data manipulation and pipe operator %>%
## 安装完成!
## Installation completed!
source("crosslink.R") # From R package crosslink, https://github.com/zzwch/crosslink
source("layout.R") # From R package crosslink, https://github.com/zzwch/crosslink
source("transfromation.R") # From R package crosslink, https://github.com/zzwch/crosslink
source("utils.R") # From R package crosslink, https://github.com/zzwch/crosslink
source("crossplot.R") # From R package crosslink, https://github.com/zzwch/crosslink
library(dplyr) # 数据处理 data processing##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
图中每个点、每条线的外观设置有两种方式供你选择。理解之后就可以灵活运用了,例如有些外观用代码写,有些外观填写在输入文件里。
easy_input_nodes.csv,每个节点为一行。第一列是节点id,之后是其类别type、颜色color、大小size、透明度alpha和形状shape。例如一个节点代表一个基因;type列就写gene;颜色、大小、透明度和形状都可以代表基因的某一特征值,例如表达量等。
easy_input_edges.csv,每两个被连起来的节点为一行,前两列是两个节点的id,之后是颜色color、类型type、透明度alpha和粗细size,这些外观信息可以代表每两个节点之间关系的强度、类型等。
There are two ways to customize the appearance of each point and line in the figure. Once understood, you can apply them flexibly—for example, setting some appearances via code while specifying others in the input file.
Option 1: Define appearances in the input file with custom values Pros: WYSIWYG (What You See Is What You Get)—the output will match exactly what you write. Cons: More tedious to set up.
Option 2: Keep the input file minimal (only id and type columns required) and control appearances via plotting parameters Pros: Easier to modify; avoids manual editing for each element and integrates smoothly with upstream analysis. Cons: Less convenient than Option 1 when dealing with too many appearance variations.
Input File Formats:easy_input_nodes.csv.Each row represents a node. The first column is the node id, followed by its type, color, size, alpha (transparency), and shape.
Example: If a node represents a gene, set type as “gene.”Other columns (color, size, alpha, shape) can encode additional features (e.g., expression levels).
## id type color size alpha shape
## 1 Gene1 Gene #FEE08B 6 0.8 4
## 2 Gene2 Gene #E6F598 10 0.5 14
## 3 Gene3 Gene #3288BD 7 0.9 15
## 4 Gene4 Gene #E6F598 5 0.8 3
## 5 Gene5 Gene #9E0142 4 0.6 12
## 6 Gene6 Gene #ABDDA4 10 0.8 2
# 载入连线信息
# Load the connection information
edges <- read.csv("easy_input_edges.csv", header = T)
head(edges)## source target color type alpha size
## 1 Gene5 Mir1 #E31A1C 3 0.5 3
## 2 Gene6 Mir6 #1F78B4 1 0.6 3
## 3 Gene1 Mir2 #E31A1C 5 1.0 1
## 4 Gene9 Mir5 #1F78B4 3 0.6 1
## 5 Gene5 Mir1 #33A02C 4 0.9 1
## 6 Gene1 Mir3 #A6CEE3 3 0.7 1
# 写入想画的type
# Write the type you want to draw
columns <- list(# 如果你只有两个type(或者只想画两列),就在list里写两行。# If you only have two types (or just want to draw two columns), write two lines in the list
Gene = nodes$id[nodes$type == "Gene"],
Drug = nodes$id[nodes$type == "Drug"],
Target = nodes$id[nodes$type == "Tar"],
Pathway = nodes$id[nodes$type == "Path"]
)
columnCross2(edges, nodes, columns,
height = 1, flank_mult = rep(0.1, length(columns)), segment_shrink = 0.1,
linetype = "type", line_alpha = "alpha", line_color = "color", line_size = "size",
pt_shape = "shape", pt_alpha = "alpha",
pt_color = "color", # 外圈颜色 # Outer ring color
pt_fill = "color", # 填充颜色 # Fill color
pt_size = "size", pt_stroke = 1)## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
# 写入想画的type
# 如果你只有两个type(或者只想画两列),就在list里写两行。
# Write the type you want to draw
# If you only have two types (or just want to draw two columns), write two lines in the list.
columns <- list(
Gene = nodes$id[nodes$type == "Gene"],
Drug = nodes$id[nodes$type == "Drug"],
Target = nodes$id[nodes$type == "Tar"],
Pathway = nodes$id[nodes$type == "Path"]
)
# 以连线类型和节点形状为例,说明定义外观的两种方式,定义其他外观的方法类似
# Take the line type and node shape as an example to illustrate the two ways to define appearances, and the methods for defining other appearances are similar
columnCross2(edges, nodes, columns,
height = 1, flank_mult = rep(0.1, length(columns)), segment_shrink = 0.1,
linetype = 1, # 默认值,所有连线都画成直线 # By default, all lines are drawn as straight lines
line_alpha = "alpha", line_color = "color", line_size = "size" ,
#pt_shape = 21, # 统一画成实心圆 # Draw a solid circle in unison
# 或者Drug画成空心圆,其余画成实心圆 # Or the Drug is drawn as a hollow circle, and the rest is drawn as a solid circle
pt_shape = c(rep(16, length(columns$Gene)), rep(1, length(columns$Drug)), rep(16, (length(columns$Target) + length(columns$Pathway)))),
pt_alpha = .8, # 统一设置透明度 # Set transparency uniformly
pt_color = "color", pt_fill = "color", pt_size = "size",
pt_stroke = 3) # 让空心圆的边粗一些 # Make the edges of the hollow circle thicker如果某类节点太多,可以排成多列,就像需求描述的第二个例子那样。
If there are too many nodes of a certain type, you can arrange them into multiple columns, as in the second example of the requirements description.
## id type color size alpha shape
## 1 P1 P firebrick 7 0.8 15
## 2 P2 P firebrick 4 0.9 15
## 3 P3 P firebrick 8 0.8 15
## 4 P4 P firebrick 9 0.6 15
## 5 P5 P firebrick 10 0.7 15
## 6 P6 P firebrick 4 0.9 15
# 载入连线信息
# Load connection information
edges <- read.csv("easy_input2_edges.csv", header = T)
head(edges)## source target color
## 1 P15 RBP20 red
## 2 P10 RBP17 red
## 3 P17 RBP4 red
## 4 P2 RBP14 red
## 5 P14 RBP4 red
## 6 P5 RBP5 red
# 这里把P和N都拆成两列,当然你也可以拆成更多列
# Split both P and N into two columns, but you can also split them into more columns
columns <- list(
P1 = nodes$id[nodes$type == "P"][1:15],
P2 = nodes$id[nodes$type == "P"][16:30],
RBP = nodes$id[nodes$type == "RBP"],
N1 = nodes$id[nodes$type == "N"][1:15],
N2 = nodes$id[nodes$type == "N"][16:30]
)
seq_len(length(columns))## [1] 1 2 3 4 5
# 以连线类型和节点形状为例,说明定义外观的两种方式,定义其他外观的方法类似
# Take the line type and node shape as an example to illustrate the two ways to define appearances, and the methods for defining other appearances are similar
columnCross2(edges, nodes, columns,
height = 1,
# 默认值是1,2,3,4,5,每列之间是等距的
# 我们想让两边的两列距离近些,就这样改
# The default values are 1, 2, 3, 4, 5, and each column is equidistant
# We want to make the two columns on both sides closer, so change it like this
column_x = c(1, 1.5, 3, 4.5, 5),
# 默认值都是0.1
# 我们想让中间RBP那列短一些,就这样改
# The default value is 0.1
# We want to make the middle RBP column shorter, so change it like this
flank_mult = c(0.1, 0.1, 0.15, 0.1, 0.1),
segment_shrink = 0,
line_alpha = .2, line_size = 1, line_color = "color",
pt_shape = "shape", pt_alpha = "alpha", pt_color = "color", pt_fill = "color", pt_size = "size", pt_stroke = 1)输出的pdf文件是矢量图,可以用矢量图编辑器打开(例如Illustrator)调整图形、文字。
The output pdf file is a vector image, which can be opened with a vector editor (e.g. Illustrator) to adjust graphics, text.
# 节点的颜色
# The color of the node
node_colors <- RColorBrewer::brewer.pal(11, "Spectral")
# 连线的颜色
# The color of the wire
edge_colors <- RColorBrewer::brewer.pal(12, "Paired")
# nodes
nodes <- data.frame(
id = c(paste0("Gene", 1:10), paste0("Meth", 1:10),
paste0("Mir", 1:6), paste0("Drug", 1:8),
paste0("Tar", 1:8), paste0("Path", 1:6)),
type = c(rep("Gene", 10), rep("Meth", 10),
rep("Mir", 6), rep("Drug", 8),
rep("Tar", 8), rep("Path", 6)),
color = sample(node_colors, 48, replace = T),
size = sample(3:10, 48, replace = T),
alpha = sample((5:10)/10, 48, replace = T),
shape = sample(1:20, 48, replace = T)
)
write.csv(nodes, "easy_input_nodes.csv", quote = F, row.names = F)
# edges
edges <- data.frame(rbind(
# gene vs mir
data.frame(
source = sample(nodes$id[nodes$type == "Gene"],
replace = T, 30),
target = sample(nodes$id[nodes$type == "Mir"],
replace = T, 30)),
# gene vs drug
data.frame(
source = sample(nodes$id[nodes$type == "Gene"],
replace = T, 100),
target = sample(nodes$id[nodes$type == "Drug"],
replace = T, 100)),
# meth vs drug
data.frame(
source = sample(nodes$id[nodes$type == "Meth"],
replace = T, 100),
target = sample(nodes$id[nodes$type == "Drug"],
replace = T, 100)),
# mir vs drug
data.frame(
source = sample(nodes$id[nodes$type == "Mir"],
replace = T, 20),
target = sample(nodes$id[nodes$type == "Drug"],
replace = T, 20)),
# drug vs target
data.frame(
source = nodes$id[nodes$type == "Drug"],
target = nodes$id[nodes$type == "Tar"]),
# target vs path
data.frame(
source = sample(nodes$id[nodes$type == "Tar"],
replace = T, 15),
target = sample(nodes$id[nodes$type == "Path"],
replace = T, 15))
),
color = sample(edge_colors, 273, replace = T),
type = sample(1:5, 273, replace = T),
alpha = sample((5:10)/10, 273, replace = T),
size = sample(1:3, 273, replace = T))
write.csv(edges, "easy_input_edges.csv", quote = F, row.names = F)# 节点的颜色
# The color of the node
node_colors <- RColorBrewer::brewer.pal(11, "Spectral")
# 连线的颜色
# The color of the wire
edge_colors <- RColorBrewer::brewer.pal(12, "Paired")
# nodes
nodes <- data.frame(
id = c(paste0("P", 1:30),
paste0("RBP", 1:20),
paste0("N", 1:30)),
type = c(rep("P", 30),
rep("RBP", 20),
rep("N", 30)),
color = c(rep("firebrick",30), sample(node_colors, 20,replace = T), rep("dodgerblue", 30)),
size = sample(3:10, 80, replace = T),
alpha = sample((5:10)/10, 80, replace = T),
shape = c(rep(15,30), rep(16, 20), rep(15, 30))
)
write.csv(nodes, "easy_input2_nodes.csv", quote = F, row.names = F)
# edges
edges <- data.frame(rbind(
# Positive pathway vs RBP
data.frame(
source = sample(nodes$id[nodes$type == "P"],
replace = T, 100),
target = sample(nodes$id[nodes$type == "RBP"],
replace = T, 100)),
# Negative pathway vs RBP
data.frame(
source = sample(nodes$id[nodes$type == "N"],
replace = T, 100),
target = sample(nodes$id[nodes$type == "RBP"],
replace = T, 100))
),
color = c(rep("red", 100), rep("cornflowerblue", 100)))
write.csv(edges, "easy_input2_edges.csv", quote = F, row.names = F)## R version 4.5.2 (2025-10-31)
## Platform: x86_64-pc-linux-gnu
## Running under: Ubuntu 24.04.3 LTS
##
## Matrix products: default
## BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
## LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.26.so; LAPACK version 3.12.0
##
## locale:
## [1] LC_CTYPE=C.UTF-8 LC_NUMERIC=C LC_TIME=C.UTF-8
## [4] LC_COLLATE=C.UTF-8 LC_MONETARY=C.UTF-8 LC_MESSAGES=C.UTF-8
## [7] LC_PAPER=C.UTF-8 LC_NAME=C LC_ADDRESS=C
## [10] LC_TELEPHONE=C LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C
##
## time zone: UTC
## tzcode source: system (glibc)
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] scales_1.4.0 ggplot2_4.0.1 dplyr_1.1.4
##
## loaded via a namespace (and not attached):
## [1] crayon_1.5.3 vctrs_0.6.5 cli_3.6.5 knitr_1.50
## [5] rlang_1.1.6 xfun_0.54 generics_0.1.4 textshaping_1.0.4
## [9] S7_0.2.1 jsonlite_2.0.0 labeling_0.4.3 glue_1.8.0
## [13] htmltools_0.5.8.1 ragg_1.5.0 sass_0.4.10 rmarkdown_2.30
## [17] grid_4.5.2 evaluate_1.0.5 jquerylib_0.1.4 tibble_3.3.0
## [21] fastmap_1.2.0 yaml_2.3.10 lifecycle_1.0.4 compiler_4.5.2
## [25] RColorBrewer_1.1-3 pkgconfig_2.0.3 systemfonts_1.3.1 farver_2.1.2
## [29] digest_0.6.39 R6_2.6.1 tidyselect_1.2.1 pillar_1.11.1
## [33] magrittr_2.0.4 bslib_0.9.0 withr_3.0.2 tools_4.5.2
## [37] gtable_0.3.6 cachem_1.1.0